package com.lightjet.macross.base.awf.controller;

import com.lightjet.macross.base.awf.domain.BizAgent;
import com.lightjet.macross.base.awf.domain.BizFormIndex;
import com.lightjet.macross.base.awf.dto.NodeDefDTO;
import com.lightjet.macross.base.awf.dto.ProcInstDTO;
import com.lightjet.macross.base.feign.api.controller.PrincipalController;
import com.lightjet.macross.base.feign.api.domain.AuthUser;
import com.lightjet.macross.base.awf.dto.FlowDataDTO;
import com.lightjet.macross.base.awf.service.BizAgentService;
import com.lightjet.macross.base.awf.service.BizFormIndexService;
import com.lightjet.macross.base.awf.service.BizProcessConfigService;
import com.lightjet.macross.base.awf.service.ProcessService;
import com.lightjet.macross.base.awf.dto.ProcDefDTO;
import com.lightjet.macross.base.feign.api.service.upms.UPMSDataMappingService;
import com.lightjet.macross.common.dto.ResponseDTO;
import com.lightjet.macross.common.util.FormatUtil;
import com.lightjet.macross.common.util.RespUtil;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Example;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

import static com.lightjet.macross.base.awf.config.AWFConstants.PROCESSFIX_ADMIN_ID;

@RestController
@RequestMapping("/api/run")
@Scope("request")
@Log
@Api(tags="AWF业务流程服务-运行相关接口集")
public class RunningController extends PrincipalController {

    @Resource
    private ProcessService processService;

    @Resource
    private BizFormIndexService bizFormIndexService;

    @Resource
    private BizAgentService bizAgentService;

    @Resource
    private BizProcessConfigService bizProcessConfigService;

    @Resource
    private UPMSDataMappingService upmsDataMappingService;

    @Value("${biz.usersystembeanname:macross}")
    private String usersystembeanname;

    //发起流程
    @PostMapping("/start")
    @ApiOperation(value = "流程发起接口", notes = "根据流程相关信息发起新的流程")
    public ResponseDTO<String> Start(
            @ApiParam(name = "startFormDTO",value = "流程发起表单数据传输类Json",required = true) @RequestBody FlowDataDTO startFormDTO,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user
    )
    {
        if(StringUtil.isNullOrEmpty(startFormDTO.getExecutor()))
        {
            startFormDTO.setExecutor(user.getId());
        }
        return RespUtil.FromResultDTO(processService.StartProcess(startFormDTO));
    }

    //获取我的任务按任务节点的汇总信息
    @PostMapping("/tasksummary")
    @ApiOperation(value ="我的任务汇总接口", notes = "获取我的（全部或某类流程）任务汇总信息（按流程版本、节点名称）")
    public ResponseDTO<List<ProcDefDTO>> TaskSummary(
            @ApiParam(name = "pdkey", value = "流程定义key，为空或*查询全部流程定义") String pdkey
            ,@ApiParam(name = "userid", value = "显式用户ID，为空自动调用Token对应用户信息") String userid
            ,@ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        userid = StringUtil.isNullOrEmpty(userid)?user.getId():userid;
        List<ProcDefDTO> list = (StringUtil.isNullOrEmpty(pdkey)||"*".equals(pdkey))? processService.GetMyBizTaskSummary(userid): processService.GetMyBizTaskSummary(userid,pdkey) ;
        return RespUtil.CreateOK(list);
    }

    //获取我的任务按任务节点的汇总信息
    @PostMapping("/tasksummary/keylist")
    @ApiOperation(value ="我的特定流程任务汇总接口", notes = "获取我的（部分流程，流程定义key范围为keylist参数）任务汇总信息（按流程版本、节点名称）")
    public ResponseDTO<List<ProcDefDTO>> GetTaskSummaryByProcessKeyList(
            @ApiParam(name = "keylist", value = "流程定义key，为空或*查询全部流程定义")@RequestBody List<String> keylist
            ,@ApiParam(name = "userid", value = "显式用户ID，为空自动调用Token对应用户信息") String userid
            ,@ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        userid = StringUtil.isNullOrEmpty(userid)?user.getId():userid;
        List<ProcDefDTO> list = processService.GetMyBizTaskSummary(userid,keylist);
        return RespUtil.CreateOK(list);
    }

    //获取我的任务，按节点名称汇总
    @RequestMapping(value = "/mynode", method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="我的任务节点流程数据接口", notes = "获取我的（某一类流程全部或某个节点）的流程实例集合")
    public ResponseDTO<List<HashMap<String,String>>> MyNode(
            @ApiParam(name = "pdkey", value = "流程定义key",required =true) String pdkey
            ,@ApiParam(name = "nodename", value = "流程节点名称") String nodename
            ,@ApiParam(name = "userid", value = "显式用户ID，为空自动调用Token对应用户信息") String userid
            ,@ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        return RespUtil.CreateOK(processService.GetMyProcNodeFormList(pdkey,nodename,  userid = StringUtil.isNullOrEmpty(userid)?user.getId():userid));
    }

    @RequestMapping(value = "/taskform",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="任务表单数据接口", notes = "根据任务ID号获取相应表单列表")
    public ResponseDTO<List<HashMap>> TaskForm(
            @ApiParam(name = "taskid", value = "任务ID",required =true) String taskid)
    {
        try
        {
            return RespUtil.CreateOK(processService.GetPreviousFormsByTaskId(taskid));
        }
        catch (Exception e)
        {
            return RespUtil.CreateError(e.getMessage());
        }
    }

    //处理审核类表单-业务场景：业务表单不做修改，仅填写意见
    @RequestMapping(value = "/audit",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="任务表单审核处理接口", notes = "业务场景：业务表单不做修改，仅填写意见")
    public ResponseDTO<String> Audit(@ApiParam(name = "auditinfo",value = "审批信息Map：{taskid:111,comments:\"意见\",userid:\"111\",flag:\"t\"}",required = true) @RequestBody HashMap<String,String> auditinfo,
                                     @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user) //
    {
        try {
            List<HashMap> forms = processService.GetPreviousFormsByTaskId(auditinfo.get("taskid"));
            if(auditinfo.get("userid")==null ||StringUtil.isNullOrEmpty( auditinfo.get("userid")))
            {
                auditinfo.put("userid",user.getId());
            }
            HashMap<String,Object> lastForm = forms.get(0);
            FlowDataDTO form = new FlowDataDTO();
            form.setComments(auditinfo.get("comments"));
            form.setTaskId(auditinfo.get("taskid"));
            form.setExecutor(auditinfo.get("userid"));
            form.setNextrouteflag(auditinfo.get("flag"));
            form.setBizformdata(lastForm.get("bizformdata").toString());
            form.setTitle(lastForm.get("title")==null?"":lastForm.get("title").toString());
            if(lastForm.get("bizformclass")!=null && !lastForm.get("bizformclass").equals(""))
            {
                form.setBizformclass(lastForm.get("bizformclass").toString());
            }
            return RespUtil.FromResultDTO(processService.ExecuteProcess(form));
        }
        catch (Exception e)
        {
            return RespUtil.CreateError(e.getMessage());
        }
    }

    //处理业务修改类表单-业务场景：表单部分或全部字段被修改 兼容上述 Audit 方法
    @RequestMapping(value = "/process",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="任务表单通用处理接口", notes = "业务场景：单部分或全部字段被修改 兼容上述 Audit 方法")
    public ResponseDTO<String> Process(
            @ApiParam(name="formdata",value = "表单信息Json",required = true) @RequestBody FlowDataDTO formdata
            ,@ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        if(formdata.getExecutor()==null ||StringUtil.isNullOrEmpty( formdata.getExecutor()))
        {
            formdata.setExecutor(user.getId());
        }
        return RespUtil.FromResultDTO(processService.ExecuteProcess(formdata));
    }


    @RequestMapping(value = "/process/status",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="流程实例当前状态接口", notes = "根据流程实例ID获取流程当前节点信息Map：{\"nodename\":[\"candidate1\",\"candidate2\"]}")
    public ResponseDTO<Map<String, Set<String>>> ProcessStatus( //人员问题待完善
            @ApiParam(name="piid",value = "流程实例ID",required = true) String piid,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        String pdid = processService.GetProcDefIdByPIID(piid);
        String usibn = GetUSIBNByPDID(pdid);
        Map<String,Set<String>> maps = processService.GetProcInstStatus(piid);
        Set<String> sets = new HashSet<>();
        for(String node : maps.keySet())
        {
            for(String uid: maps.get(node))
            {
                sets.add(upmsDataMappingService.FindUserByIdAndUSIB(uid,usibn).getDisplayname());
            }
            maps.put(node,sets);
        }
        return RespUtil.CreateOK(maps);
    }

    @RequestMapping(value = "/task/candidate",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="任务候选人接口", notes = "根据任务号ID获取流程当前候选人集合")
    public ResponseDTO<Set<String>> TaskCandidate( //人员问题待完善
            @ApiParam(name="taskid",value = "流程任务ID",required = true) String taskid,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        List<String> list = processService.GetCandidateUsers(taskid);
        Set<String> sets = new HashSet<>();
        String pdid = processService.GetProcDefIdByTaskId(taskid);
        String usibn = GetUSIBNByPDID(pdid);
        for(String uid :list)
        {
            try
            {
                if(!PROCESSFIX_ADMIN_ID.equals(uid))
                {
                    sets.add(upmsDataMappingService.FindUserByIdAndUSIB(uid,usibn).getDisplayname());
                }
                else
                {
                    sets.add("流程管理员");
                }

            }
            catch (Exception e)
            {
                log.info("根据人员ID获取名称失败：[UPMSDataMappingService]:"+e.getMessage());
            }
        }
        return RespUtil.CreateOK(sets);
    }

    @RequestMapping(value = "/task/comment",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="任务", notes = "根据任务号ID获取流程当前候选人集合")
    public ResponseDTO<String> TaskComment(
            @ApiParam(name="taskid",value = "流程任务ID",required = true) String taskid)
    {
        HashMap map =processService.GetTaskInfoByProps(taskid,Collections.singletonList("comments"));
        if(map!=null && map.get("comments")!=null) {
            return RespUtil.CreateOK(map.get("comments").toString());
        }
        else
        {
            return RespUtil.CreateOK("未填写");
        }
    }


    //根据流程id获取相应表单索引信息
    @RequestMapping(value = "/formindex",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="流程索引信息获取接口", notes = "根据流程定义id获取key获取已建索引数据描述信息，返回值为 List<Map<String, Object>> 类型")
    public ResponseDTO<List<Map<String, Object>>> FormIndex(
            @ApiParam(name="pdid",value = "流程定义ID（Key）",required = true) String pdid,
            @ApiParam(name="only",value = "是否只显示私有索引（只显示手工建立索引，不显示公共索引），默认为空（显示公共索引信息）") String only)
    {
        List<Map<String, Object>> colMap = new ArrayList<>();
        if(StringUtil.isNullOrEmpty(only))
        {
            colMap.add(new HashMap<String, Object>() {
                {put("field", "taskId");}
                {put("visible", false);}
                {put("hidden", true);}
                {put("title", "任务ID");}
            });
            colMap.add(new HashMap<String, Object>() {
                {put("field", "procinstId");}
                {put("title", "流程ID");}
            });
            colMap.add(new HashMap<String, Object>() {
                {put("field", "nodename");}
                {put("title", "任务节点");}
            });
            colMap.add(new HashMap<String, Object>() {
                {put("field", "nodedefid");}
                {put("visible", false);}
                {put("hidden", true);}
                {put("title", "节点定义ID");}
            });
            colMap.add(new HashMap<String, Object>() {
                {put("field", "opdate");}
                {put("title", "任务开始时间");}
            });
        }

        bizFormIndexService.GetFormIndexes(pdid).forEach(e -> colMap.add(new HashMap<String, Object>() {
            {put("field", e.getIndexname());}
            {put("title", e.getIndexdisplayname());}
            {put("filter", e.getMemo());}
            {put("displaywidth", e.getDisplaywidth());}

        }));

        return RespUtil.CreateOK(colMap);
    }
    //
//
    @RequestMapping(value = "/process/summary",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="运行中流程汇总查询接口", notes = "根据流程定义名称获取运行中流程汇总信息")
    public ResponseDTO<List<ProcDefDTO>> GetRunningProcList(
            @ApiParam(name = "pdkey", value = "流程定义key，为空或*查询全部流程定义") String pdkey,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        //log.info("user:"+user.getDisplayname());
        return RespUtil.CreateOK(processService.GetRunningProcessSummary(pdkey));
    }

    @RequestMapping(value = "/process/summary/keyset",method = {RequestMethod.POST})
    @ApiOperation(value ="运行中流程汇总查询接口", notes = "根据流程定义名称集合获取集合范围中运行中流程汇总信息")
    public ResponseDTO<List<ProcDefDTO>> GetRunningProcListByKeySet(
            @ApiParam(name = "pdkeys", value = "流程定义key集合") @RequestBody Set<String> pdkeys,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        //log.info("user:"+user.getDisplayname());
        return RespUtil.CreateOK(processService.GetRunningProcessSummary(pdkeys));
    }

    @RequestMapping(value = "/procinvolved/summary/keylist",method = {RequestMethod.POST})
    @ApiOperation(value ="人员涉及流程汇总查询接口", notes = "根据人员ID及流程定义名称集合获取集合范围内设计的流程汇总信息")
    public ResponseDTO<List<ProcDefDTO>> GetRevolvedSummaryByKeySet(
            @ApiParam(name = "pdkeys", value = "流程定义key集合") @RequestBody List<String> pdkeys,
            @ApiParam(name = "userid", value = "显式用户ID，为空自动调用Token对应用户信息") String userid,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        if(pdkeys == null || pdkeys.size() == 0)
        {
            return RespUtil.CreateError("查询失败：流程定义Key集合为空");
        }
        userid = StringUtil.isNullOrEmpty(userid)?user.getId():userid;
        return RespUtil.CreateOK(processService.GetRunningInvolvedProcess(userid,pdkeys));
    }

    @RequestMapping(value = "/procinvolved/list",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="人员涉及流程明细接口", notes = "根据流程定义ID获取Token用户的涉及流程实例明细列表（List<HashMap<String,Object>>）")
    public ResponseDTO<List<HashMap<String,Object>>> GetRevolvedList(
            @ApiParam(name = "pdid", value = "流程定义ID") String pdid,
            @ApiParam(name = "usibn", value = "用户体系接口BeanName，为空默认取usersystembeanname") String usibn,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        String pdiss = processService.GetProcDesByPDID(pdid);//首先判断流程设计图中是否包含流程所属账号平台的描述信息
        if(!StringUtil.isNullOrEmpty(pdiss))
        {
            usibn = pdiss;
        }
        usibn = StringUtil.isNullOrEmpty(usibn)? usersystembeanname : usibn;
        final String beanname = usibn;
        List<HashMap<String,Object>> list =processService.GetRunningInvolvedProcessList(pdid,user.getId());
        for(HashMap<String,Object> item : list)
        {
            item.put("candidates", ((List<String>)item.get("candidates")).stream().map(
                    e-> e.equals(PROCESSFIX_ADMIN_ID)?e:upmsDataMappingService.FindUserByIdAndUSIB(e,beanname).getDisplayname() )
                    .collect(Collectors.toList()));
        }
        return RespUtil.CreateOK(list);
    }

    //
    @RequestMapping(value = "/process/list",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="运行中流程列表查询接口", notes = "根据流程定义ID获取运行中流程实例列表")
    public ResponseDTO<List<ProcInstDTO>> RunningProcDetail(
            @ApiParam(name = "pdid", value = "流程定义ID", required = true) String pdid,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        String pdiss = processService.GetProcDesByPDID(pdid);//首先判断流程设计图中是否包含流程所属账号平台的描述信息
        pdiss = StringUtil.isNullOrEmpty(pdiss)? usersystembeanname : pdiss;
        List<ProcInstDTO> list = processService.GetRunningProcessDetail(pdid);
        for(ProcInstDTO t : list)
        {
            String initiator = t.getInitiator();
            if(!StringUtil.isNullOrEmpty(initiator))
            {
                AuthUser suser = upmsDataMappingService.FindUserByIdAndUSIB(initiator,pdiss);
                if (suser != null) {
                    t.setInitiator(suser.getDisplayname());
                }
            }
        }
        return RespUtil.CreateOK(list);//ResultDTO.CreateOKResult(processService.GetRunningProcessDetail(pdid));
    }
    //
    @RequestMapping(value = "/task/defset",method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value ="流程任务节点定义查询接口", notes = "根据流程定义ID获取流程任务节点定义ID集合")
    public ResponseDTO<List<NodeDefDTO>> TaskDefSet(
            @ApiParam(name = "pdid", value = "流程定义ID", required = true) String pdid,
            @ApiParam(name = "showservicenode", value = "是否显示服务类型节点，为空不显示（默认），任意值为显示") String showservicenode)
    {
        if(pdid.equals("*"))
        {
            return RespUtil.CreateOK(processService.GetAllProcNodeDef(!StringUtil.isNullOrEmpty(showservicenode)));
        }
        else {
            //如果 pdid 是 key （没有：分割的） 则先找到该key的最新流程定义
            if (pdid.split(":").length <= 2) {
                pdid = processService.GetCurrentProcDef(pdid).getProcdefid();
            }
            return RespUtil.CreateOK(StringUtil.isNullOrEmpty(showservicenode) ? processService.GetTaskNodeDefSet(pdid) : processService.GetTaskNodeDefSetWithServiceTask(pdid));
        }
    }
    //
    @RequestMapping(value = "/process/redirect",method = {RequestMethod.POST})
    @ApiOperation(value ="运行中流程跳转接口", notes = "根据流程当前任务ID以及目标任务节点定义ID实现流程跳转")
    public ResponseDTO<String> Redirect(
            @ApiParam(name = "taskid", value = "流程任务ID", required = true) String taskid,
            @ApiParam(name = "taskdefid", value = "流程任务节点定义ID", required = true) String taskdefid,
            @ApiParam(name = "reason", value = "跳转原因") String reason,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        return RespUtil.FromResultDTO( processService.JumpTask(taskid,taskdefid, StringUtil.isNullOrEmpty(reason)?"流程跳转":reason,user.getId()));
    }
    //
    @RequestMapping(value = "/task/delegate",method = {RequestMethod.POST})
    @ApiOperation(value ="运行中流程任务转办接口", notes = "根据任务ID及目标用户id转办相应任务")
    public ResponseDTO<String> TaskDelegate(
            @ApiParam(name = "taskid", value = "流程任务ID", required = true) String taskid,
            @ApiParam(name = "targetuserid", value = "目标用户ID", required = true) String targetuserid)
    {
        return RespUtil.FromResultDTO( processService.ChangeAssinee(taskid,targetuserid));
    }
    //
    @RequestMapping(value = "/process/fix",method = {RequestMethod.POST},consumes = "application/json")
    @ApiOperation(value ="运行中流程实例修复接口", notes = "根据流程实例ID集合批量修复，参数为List<String>类型JSON")
    public ResponseDTO<String> FixTask(
            @ApiParam(name = "tiids", value = "流程实例ID列表（json对象）", required = true) @RequestBody List<String> tiids)
    {
        return RespUtil.FromResultDTO(processService.FixTask(tiids));
    }
    //
    @RequestMapping(value = "/task/list",method = {RequestMethod.POST},consumes = "application/json")
    @ApiOperation(value ="待修复任务列表接口", notes = "根据流程定义ID获取待修复流程任务的列表")
    public ResponseDTO<List<HashMap<String, String>>> TaskList(
            @ApiParam(name = "query",
                    value = "查询信息HashMap<String,Object> :{\"pdid\":\"流程定义ID\",\"sdate\":\"查询起始时间\",\"ddate\":\"查询结束时间\"} 需要分页的在map追加pageindex、pagesize 键、其他业务查询自行追加（目前尚未完成该功能） " ,
                    type="body") @RequestBody HashMap<String,String> query,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        String pdid = query.get("pdid");
        query.remove("pdid");
        String ndkey = query.get("ndkey");
        query.remove("ndkey");
        String userid = "awf_fix_admin";//query.get("userid");
/*        query.remove("userid");
        if(!"awf_fix_admin".equals(userid))
        {
            userid = user.getId();
        }*/
        return RespUtil.CreateOK(processService.GetMyBizTaskByQuery(userid,pdid,ndkey,query));
    }


    @RequestMapping(value = "/agent/mine",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="我的已授权代理查询接口", notes = "根据是否生效标志（0/1）获取本人创建的流程代理记录列表")
    public ResponseDTO<List<BizAgent>> MyAgentList(
            @ApiParam(name = "enable",value = "是否生效",required = true, type = "query") byte enable,
            @ApiIgnore @ModelAttribute("CurrentUser") AuthUser user)
    {
        List<BizAgent> grantedlist = bizAgentService.GetAgentsByPrincipalId(user.getId(),enable);
        for(BizAgent bizAgent : grantedlist)
        {
            bizAgent.setOpername(upmsDataMappingService.FindUserByIdAndUSIB(bizAgent.getOperId(),user.getUsibn()).getDisplayname());
            bizAgent.setAgentname(upmsDataMappingService.FindUserByIdAndUSIB(bizAgent.getAgentId(),user.getUsibn()).getDisplayname());
            bizAgent.setPrincipalname(upmsDataMappingService.FindUserByIdAndUSIB(bizAgent.getPrincipalId(),user.getUsibn()).getDisplayname());
            bizAgent.setStarttimetext(FormatUtil.GetDateTimeStr(bizAgent.getStarttime()));
            bizAgent.setEndtimetext(FormatUtil.GetDateTimeStr(bizAgent.getEndtime()));
        }
        return RespUtil.CreateOK(grantedlist);
    }
    //
    @RequestMapping(value = "/agent/all",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value ="所有人已授权代理查询接口", notes = "根据是否生效标志（0/1）及系统用户体系标识（默认为配置implementAuthToken）获取所有人已创建的流程代理记录列表")
    public ResponseDTO<List<BizAgent>> AgentList(
            @ApiParam(name = "enable",value = "是否生效",required = true, type = "query") byte enable,
            @ApiParam(name = "beanname",value = "用户体系标识",type = "query") String beanname,
            @ModelAttribute("CurrentUser") AuthUser user)
    {
        List<BizAgent> grantedlist = bizAgentService.GetAgentsByPrincipalId("*",enable);
        beanname = StringUtil.isNullOrEmpty(beanname)?user.getUsibn():beanname;
        for(BizAgent bizAgent : grantedlist)
        {
            bizAgent.setOpername(upmsDataMappingService.FindUserByIdAndUSIB(bizAgent.getOperId(),beanname).getDisplayname());
            bizAgent.setAgentname(upmsDataMappingService.FindUserByIdAndUSIB(bizAgent.getAgentId(),beanname).getDisplayname());
            bizAgent.setPrincipalname(upmsDataMappingService.FindUserByIdAndUSIB(bizAgent.getPrincipalId(),beanname).getDisplayname());
            bizAgent.setStarttimetext(FormatUtil.GetDateTimeStr(bizAgent.getStarttime()));
            bizAgent.setEndtimetext(FormatUtil.GetDateTimeStr(bizAgent.getEndtime()));
        }
        return RespUtil.CreateOK(grantedlist);
    }
    //
    @PostMapping(value="/agent",consumes = "application/json")
    @ApiOperation(value ="创建代理接口", notes = "根据代理对象实体Json创建，并可指定是否需要转交在途流程（trans = \"1\"）")
    public ResponseDTO<String> CreateAgent(
            @ApiParam(name = "agents",value = "代理信息列表List泛型Json",required = true, type = "body") @RequestBody List<BizAgent> agents,
            @ApiParam(name = "trans",value = "是否转办在途任务(默认不转办 传文本值1 表示需要转办)", type = "query") String trans)
    {
        return RespUtil.FromResultDTO(bizAgentService.GrantAgent(agents,trans.equals("1")));
    }
    //
    @Transactional
    @PostMapping(value="/agent/revoke",consumes = "application/json")
    @ApiOperation(value ="代理撤销接口", notes = "根据代理ID列表Json撤销代理")
    public ResponseDTO<String> ReVokeAgent(
            @ApiParam(name = "ids",value = "代理ID列表Json",required = true, type = "body") @RequestBody List<Integer> ids)
    {
        return RespUtil.FromResultDTO(bizAgentService.BatchExpire(ids));
    }
    //
    @GetMapping("/formindex/list")
    @ApiOperation(value ="表单索引列表查询接口", notes = "根据流程定义ID获取所有表单索引项")
    public ResponseDTO<List<BizFormIndex>> FormIndexList(@ApiParam(name = "pdid",value = "流程定义ID", type = "query") String pdid)
    {
        if(pdid.equals("*"))
        {
            return RespUtil.CreateOK(bizFormIndexService.FindAll());
        }
        else
        {
            BizFormIndex query = new BizFormIndex();
            query.setProcinstdefId(pdid);
            query.setSort(null);
            return RespUtil.CreateOK(bizFormIndexService.FindAll(Example.of(query)));
        }
    }
    //
    @DeleteMapping(value="/formindex/batch",consumes = "application/json")
    @ApiOperation(value ="表单索引删除接口", notes = "根据表单索引ID列表Json删除表单索引")
    @Transactional
    public ResponseDTO<String> FormIndexDelete(
            @ApiParam(name = "ids",value = "表单索引ID列表Json",required = true, type = "body") @RequestBody List<Integer> ids) {
        try {
            bizFormIndexService.DeleteInBatch(ids.stream().map(BizFormIndex::new).collect(Collectors.toList()));
            return RespUtil.CreateOK();
        }
        catch (Exception e)
        {
            return RespUtil.CreateError("删除索引失败："+e.getMessage());
        }
    }
    //
    @PostMapping(value="/formindex",consumes = "application/json")
    @ApiOperation(value ="表单索引创建接口", notes = "根据表单索引实体类Json进行创建")
    public ResponseDTO<String> FormIndexCreate(
            @ApiParam(name = "bizFormIndex",value = "表单索引实体类Json",required = true, type = "body") @RequestBody BizFormIndex bizFormIndex)
    {
        try {
            bizFormIndexService.CreateAndFlush(bizFormIndex);
            return RespUtil.CreateOK();
        }
        catch (Exception e)
        {
            return RespUtil.CreateError("新建表单索引失败："+e.getMessage());
        }
    }
    //
    @PutMapping(value="/formindex",consumes = "application/json")
    @ApiOperation(value ="表单索引更新接口", notes = "根据表单索引实体类Json进行更新")
    public ResponseDTO<String> FormIndexUpdate(
            @ApiParam(name = "bizFormIndex",value = "表单索引实体类Json",required = true, type = "body") @RequestBody BizFormIndex bizFormIndex)
    {
        try{
            BizFormIndex original = bizFormIndexService.GetOne(bizFormIndex.getId());
            original.setProcinstdefId(bizFormIndex.getProcinstdefId());
            original.setSort(bizFormIndex.getSort());
            original.setIndexdisplayname(bizFormIndex.getIndexdisplayname());
            original.setIndexname(bizFormIndex.getIndexname());
            original.setIndexpath(bizFormIndex.getIndexpath());
            original.setMemo(bizFormIndex.getMemo());
            original.setPattern(bizFormIndex.getPattern());
            original.setDisplaywidth(bizFormIndex.getDisplaywidth());
            bizFormIndexService.UpdateAndFlush(original);
            return RespUtil.CreateOK();
        }
        catch (Exception e)
        {
            return RespUtil.CreateError("更新表单索引失败："+e.getMessage());
        }
    }
    //
    @PostMapping("/formindex/refresh")
    @ApiOperation(value ="表单索引刷新接口", notes = "根据表单索引ID对已生成的表单进行刷新（重新抽取表单信息建立索引）")
    public ResponseDTO<String> FormIndexRefresh(@ApiParam(name = "id",value = "表单索引id",required = true, type = "query") Integer id)
    {
        return RespUtil.FromResultDTO(processService.RefreshHisForm(new BizFormIndex(id)));
    }

    @GetMapping("/def/doc")
    @ApiOperation(value ="流程定义document查询接口", notes = "根据流程定义ID获取流程document属性值，主要用于存放该流程涉及的人员体系标识")
    public ResponseDTO<String> GetProcessUserBean(@ApiParam(name = "keywords",value = "流程定义ID",type = "query") String pdid)
    {
        return RespUtil.CreateOK(processService.GetProcDesByPDID(pdid));
    }


    @GetMapping("/bizformdata")
    @ApiOperation(value ="流程业务表单查询接口", notes = "根据流程任务ID获取业务表单信息Json文本")
    public ResponseDTO<Object> GetBizFormData(@ApiParam(name = "taskid",value = "任务ID",type = "query") String taskid)
    {
        return RespUtil.FromResultDTO(processService.GetBizFormDataByTaskId(taskid));
    }

    @PutMapping("/bizformdata")
    @ApiOperation(value ="流程业务表单更新接口", notes = "根据流程任务ID、任务表单Json文本更新任务的表单信息字段")
    public ResponseDTO<String> UpdateBizFormData(
            @ApiParam(name = "taskid",value = "任务ID",type = "query") String taskid,
            @ApiParam(name = "form",value = "任务表单信息",type = "query") String form)
    {
        return  RespUtil.FromResultDTO(processService.UpdateFormData(taskid,form));
    }

    private String GetUSIBNByPDID(String pdid){
        String pdiss = processService.GetProcDesByPDID(pdid);//首先判断流程设计图中是否包含流程所属账号平台的描述信息
        return StringUtil.isNullOrEmpty(pdiss)? usersystembeanname : pdiss;
    }
}
